package cn.lili.modules.union.serviceimpl;

import cn.hutool.core.date.DateTime;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.member.entity.dos.*;
import cn.lili.modules.member.entity.dto.UnionAddDTO;
import cn.lili.modules.member.entity.dto.UnionNoticeAddDTO;
import cn.lili.modules.member.service.UserService;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.union.mapper.UnionMapper;
import cn.lili.modules.union.mapper.UnionNoticeMapper;
import cn.lili.modules.union.service.UnionMemberService;
import cn.lili.modules.union.service.UnionNoticeService;
import cn.lili.modules.union.service.UnionService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.routing.UnionRoutingKey;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class UnionNoticeServiceImpl extends ServiceImpl<UnionNoticeMapper, UnionNotice>
        implements UnionNoticeService {


    @Resource
    private UnionMapper unionMapper;

    private final ApplicationEventPublisher applicationEventPublisher;

    private final AmqpExchangeProperties amqpExchangeProperties;

    /**
     * 分页查询工会公告
     * @param pageVO
     * @return
     */
    @Override
    public Page<UnionNotice> getByPage (String unionId, PageVO pageVO) {
        LambdaQueryWrapper<UnionNotice> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UnionNotice::getUnionId, unionId);
        queryWrapper.eq(UnionNotice::getDeleteFlag, false);
        queryWrapper.orderByDesc(UnionNotice::getPubtime);
        Page<UnionNotice> page = this.page(PageUtil.initPage(pageVO), queryWrapper);
        return page;
    }

    /**
     * 发布公会
     * @param unionNoticeAddDTO
     */
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void add (UnionNoticeAddDTO unionNoticeAddDTO) {
        if (StringUtils.isEmpty(unionNoticeAddDTO.getContent())
                || StringUtils.isEmpty(unionNoticeAddDTO.getUnionId())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }

        Union union = unionMapper.selectById(unionNoticeAddDTO.getUnionId());
        if(null == union){
            throw new ServiceException(ResultCode.UNION_NOT_EXIST);
        }

        if(!union.getChairmanId().equals(UserContext.getCurrentId())){
            throw new ServiceException(ResultCode.INVALID_OPERATION);
        }

        UnionNotice notice = new UnionNotice(unionNoticeAddDTO);
        notice.setPubtime(new Date());

        if(this.save(notice)){
            UnionLog unionLog = UnionLog.builder()
                    .operationRemark("发布工会公告:" + notice.getContent())
                    .createTime(new Date())
                    .unionId(union.getId())
                    .operationUserId(UserContext.getCurrentId())
                    .operationUserName(Objects.requireNonNull(UserContext.getCurrentUser()).getUsername())
                    .build();

            applicationEventPublisher.publishEvent(
                    TransactionCommitSendMQEvent.builder()
                            .source("UNION_LOG")
                            .exchange(amqpExchangeProperties.getUnion())
                            .routingKey(UnionRoutingKey.ADD_UNION_LOG)
                            .message(unionLog)
                            .build());
        }

    }

    @Override
    public void edit(UnionNoticeAddDTO unionNoticeAddDTO) {

        if (StringUtils.isEmpty(unionNoticeAddDTO.getContent()) || StringUtils.isEmpty(unionNoticeAddDTO.getId())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }

        UnionNotice unionNotice = this.getById(unionNoticeAddDTO.getId());
        if(null == unionNotice){
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }

        Union union = unionMapper.selectById(unionNotice.getUnionId());
        if(null == union){
            throw new ServiceException(ResultCode.UNION_NOT_EXIST);
        }

        if(!union.getChairmanId().equals(UserContext.getCurrentId())){
            throw new ServiceException(ResultCode.INVALID_OPERATION);
        }

        String oriNotice = unionNotice.getContent();
        unionNotice.setContent(unionNoticeAddDTO.getContent());
        unionNotice.setPubtime(new Date());

        if(this.updateById(unionNotice)){
            UnionLog unionLog = UnionLog.builder()
                    .operationRemark("工会公告的内容【"+oriNotice+"】更改为：【"+unionNotice.getContent()+"】")
                    .createTime(new Date())
                    .unionId(union.getId())
                    .operationUserId(UserContext.getCurrentId())
                    .operationUserName(Objects.requireNonNull(UserContext.getCurrentUser()).getUsername())
                    .build();

            applicationEventPublisher.publishEvent(
                    TransactionCommitSendMQEvent.builder()
                            .source("UNION_LOG")
                            .exchange(amqpExchangeProperties.getUnion())
                            .routingKey(UnionRoutingKey.ADD_UNION_LOG)
                            .message(unionLog)
                            .build());
        }
    }

    @Override
    public void delete(UnionNoticeAddDTO unionNoticeAddDTO) {
        if (StringUtils.isEmpty(unionNoticeAddDTO.getId())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }

        UnionNotice unionNotice = this.getById(unionNoticeAddDTO.getId());
        if(null == unionNotice){
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }

        Union union = unionMapper.selectById(unionNotice.getUnionId());
        if(null == union){
            throw new ServiceException(ResultCode.UNION_NOT_EXIST);
        }

        if(!union.getChairmanId().equals(UserContext.getCurrentId())){
            throw new ServiceException(ResultCode.INVALID_OPERATION);
        }

        unionNotice.setDeleteFlag(true);

        LambdaUpdateWrapper<UnionNotice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(UnionNotice::getDeleteFlag,true);
        updateWrapper.eq(UnionNotice::getId,unionNotice.getId());
        int result = this.baseMapper.update(null,updateWrapper);

        if(result>0){
            UnionLog unionLog = UnionLog.builder()
                    .operationRemark("删除公告【"+unionNotice.getContent()+"】")
                    .createTime(new Date())
                    .unionId(union.getId())
                    .operationUserId(UserContext.getCurrentId())
                    .operationUserName(Objects.requireNonNull(UserContext.getCurrentUser()).getUsername())
                    .build();

            applicationEventPublisher.publishEvent(
                    TransactionCommitSendMQEvent.builder()
                            .source("UNION_LOG")
                            .exchange(amqpExchangeProperties.getUnion())
                            .routingKey(UnionRoutingKey.ADD_UNION_LOG)
                            .message(unionLog)
                            .build());
        }
    }

}
